約 5,162,380 件
https://w.atwiki.jp/tutokoe/pages/12.html
徳井「イワシハラです」 カナちゃん 気付いたら来ていた2回目 サカモトさん(小西真奈美似) カナちゃんは「全力投球!!妹尾和夫ですの本カズぼん。」に載ってる 徳井お風呂場で妹のおしっこ 羽谷はブラザーコンプレックス 福田はマザコン 海外からのお便り コタツの無い家で育った羽谷アナ コーナーの告知
https://w.atwiki.jp/akasatanahama/pages/89.html
特殊な形のブロックを追加する。 今回は、アルミ製の金床を追加する。 (……としたいのだが、金床のGUIに関しては、実装していない。悪しからず。) この内容はとても難解なものを含んでいるうえ、汎用性に乏しい。 そのため、更に汎用性の高いものを作る場合は、net.minecraft.client.rendererのRenderBlocksを参照。 AluminiumMod AluminiumMod.java +長いので囲みます package aluminiummod.common; import net.minecraft.block.Block; import net.minecraft.creativetab.CreativeTabs; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; /** * * @author Akasata Nahama Tom Kate YOU!! * */ @Mod(modid = "AluminiumMod", name = "Aluminium Mod") public class AluminiumMod { //追加するブロックの定義 /*public static Block * ;*/ public static Block AnvilAluminium; //レンダーIDの取得 public static int RenderID; @EventHandler public void perInit(FMLPreInitializationEvent event) { /*ブロックの実装。詳細割愛。*/ AnvilAluminium = new AnvilAluminium(); AnvilAluminium.setCreativeTab(CreativeTabs.tabBlock); AnvilAluminium.setBlockName("blockAluminium"); AnvilAluminium.setBlockTextureName("aluminiummod aluminium_anvil"); GameRegistry.registerBlock(AnvilAluminium, "AnvilAluminium"); } @EventHandler public void init (FMLInitializationEvent event) { /*FMLCommonHandler.instance().getSide() で、クライアントサイドでのみの動作としている。*/ if(FMLCommonHandler.instance().getSide() == Side.CLIENT) { /*レンダーIDの設定。 * RenderingRegistry.getNextAvailableRenderId() で、未使用のレンダーIDを取得する。*/ this.RenderID = RenderingRegistry.getNextAvailableRenderId(); /*ブロックのレンダラ―を設定する。 *RenderingRegistry.registerBlockHandler(ISimpleBlockRenderingHandler); */ RenderingRegistry.registerBlockHandler(new RenderAnvilAluminium()); } } AnvilAluminium.java +長いので囲みます package aluminiummod.common; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.world.IBlockAccess; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class AnvilAluminium extends Block{ public AnvilAluminium() { super(Material.rock); } /**レンダーIDを返す。**/ @Override public int getRenderType() { return AluminiumMod.RenderID; } /**ブロックが透けるか否かを返す。**/ @SideOnly(Side.CLIENT) public boolean shouldSideBeRendered(IBlockAccess p_149646_1_, int p_149646_2_, int p_149646_3_, int p_149646_4_, int p_149646_5_) { return true; } /**通常のブロックでないかを返す。*/ public boolean renderAsNormalBlock() { return false; } /**ブロックが透明か否かを返す。*/ public boolean isOpaqueCube() { return false; } RenderAnvilAluminium.java +長いので囲みます package aluminiummod.common; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.world.IBlockAccess; import org.lwjgl.opengl.GL11; import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; public class RenderAnvilAluminium implements ISimpleBlockRenderingHandler { /**インベントリ内でブロックをレンダリングするメソッド。もしshouldRender3DInInventoryがfalseなら空でもいいかも。**/ @Override public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { if (modelId == this.getRenderId()) { float f = 0; f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.75F, 0.25F, 0.75F ,false); f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.5F, 0.0625F, 0.625F ,false); f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.25F, 0.3125F, 0.5F ,false); this.renderAlumiAnvil(block, renderer, metadata, f, 0.625F, 0.375F, 1.0F ,false); } } /**ワールド内でブロックをレンダリングするメソッド**/ @Override public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { if (modelId == this.getRenderId()) { /*レンダリングする立方体のサイズを決めるメソッド。 * setRenderBounds(始点X, 始点Y, 始点Z, 終点X, 終点Y, 終点Z)*/ renderer.setRenderBounds(0.1D, 0.0D, 0.1D, 0.9D, 0.2D, 0.9D); /*レンダリングするメソッド。 * renderStandardBlock(block, x, y, z);*/ renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.25D, 0.2D, 0.25D, 0.75D, 0.3D, 0.75D); renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.3D, 0.3D, 0.2D, 0.7D, 0.6D, 0.8D); renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.2D, 0.6D, 0.0D, 0.8D, 1.0D, 1.0D); renderer.renderStandardBlock(block, x, y, z); return true; } return false; } @Override /**インベントリ内で3Dレンダリングするか否かを返すメソッド**/ public boolean shouldRender3DInInventory(int modelId) { return true; } /**自身のレンダーIDを返すメソッド**/ @Override public int getRenderId() { return AluminiumMod.RenderID; } protected float renderAlumiAnvil(Block block , RenderBlocks renderer , int metadata , float sides1 , float sides2 , float sides3 , float sides4 , boolean flg) { /**詳しい説明はカット。ここは難しいため、基本的にはshouldRender3DInInventoryをfalseにすることをお勧めする。**/ if(flg) { float f = sides2; sides2 = sides4; sides4 =f; } sides2 /= 2.0F; sides4 /= 2.0F; renderer.setRenderBounds((double)(0.5F - sides2), (double)sides1, (double)(0.5F - sides4), (double)(0.5F + sides2), (double)(sides1 + sides3), (double)(0.5F + sides4)); /*これより下は、ブロックを各面ごとにレンダリングしている。*/ Tessellator tessellator = Tessellator.instance; GL11.glTranslatef(-0.5F, -0.5F, -0.5F); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, -1.0F, 0.0F); renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 1.0F, 0.0F); renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 1, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, -1.0F); renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 2, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, 1.0F); renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 3, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(-1.0F, 0.0F, 0.0F); renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 4, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(1.0F, 0.0F, 0.0F); renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, metadata)); tessellator.draw(); GL11.glTranslatef(0.5F, 0.5F, 0.5F); renderer.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); return sides1 + sides3; } 解説 RenderAnvilAluminium この中では、インベントリ内でのレンダリングが一番難しいはずである。 もし大変ならば、shouldRender3DInInventoryをfalseにすればインベントリにはテクスチャのみが表示されるため、作業が楽になる。 コメント この項目に関する質問などをどうぞ。 ページ左のサイト内リンクからのリンクが間違っていると思います - 名無しさん 2015-07-08 23 19 57 ご指摘ありがとうございます。修正しました。 - 赤砂蛇凪浜 2015-07-09 09 55 44 赤砂蛇凪浜様(そうでしょうか)、おはようございます - Dao_Za 2016-04-01 10 07 32 赤砂蛇凪浜様(そうでしょうか)、おはようございます!中国のファンです。昨日夜このサイトを拝見いたしまして、即刻ファンになります~一つご質問がございますが、どうやて、ブロックのbnound大きさを設置しますでしょうか。AnvilAluminium.javaにsetBoundなどを高さ3.0のブロックに設置しましたが、上から踏んた時、画面が痙攣のようになりましたwwww。ほかのmodを読んでいましたが、onEntityCollidedWithBlockという方法でしょうか。 - Dao_Za 2016-04-01 10 12 18 setBlockBoundsの引数で、ブロックの大きさを設定することができます。また、getCollisionBoundingBoxFromPoolをオーバーライドすると衝突判定だけを設定することができます。衝突判定は、Yに2.0Fより大きい値を設定するとうまく反映できず、画面が荒ぶるようです。onEntityCollidedWithBlockは、Entityがブロックに触れているときの処理です。 - 赤砂蛇凪浜 2016-04-01 14 57 54 ありがとうございます。あの、手持ち時の3D形をどうやって設置しますか。現在椅子の形を作りたく、RenderAluminumファイルでのrenderInventoryBlockで設置して、どうか真ん中から広げて、例えば0.2F,0.3F,0.4Fで、0.2X0.4の柱になってしまいます。(あるいは最後のrenderAlumiAnvilのところで設置?ほかのMOD内容を見て、renderAlumiAnvilのところはみんなほぼお同じcodeですが。) - Dao_Za 2016-04-02 00 32 33 こんにちは。もう一点ですが、放置するときに椅子の向き方向の調整案例がございますでしょうか。 - Dao_Za 2016-04-02 12 05 08 上記二つの質問ですが、いまいち意図がつかめませんでした。(「0.2F,0.3F,0.4F」とはどこの数値でしょうか?)私もあまり得意な分野ではないので、的確な返答ができないかもしれません。申し訳ありません。 - 赤砂蛇凪浜 2016-04-04 07 52 30 説明不足でした申し訳ございませんでした。0.2とかは仮説の数字で無視すればOKです~あの、上の計算式で三つ数字の意味を知りたいですが:「f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.75F, 0.25F, 0.75F ,false);」の中の0.75、0.25、0.75の機能はそれぞれなんでしょうかね? - Dao_Za 2016-04-05 18 49 32 renderAlumiAnvilは、金床のレンダリングを行うメソッドです。sides1は始点の高さ、sides2,sides3,sides4はそれぞれ立方体のx,y,z方向の長さです。この三つで立方体の大きさを表せます。 - Tom Kate 2016-04-05 21 04 45 こんばんは。プレイヤーの向きによってカスタムモデルの向きを変えるようなブロック(例:フェンスゲート、階段等)はどのようにして追加するのでしょうか。 - modder 2016-05-11 00 07 21 返信遅くなってしまいすみません。バニラのフェンスゲートと同様、onBlockPlacedByで設置時のプレイヤーの向きに応じてメタデータを設定し、レンダリング時にメタデータを取得して描画する向きを決めればよいかと思います。 - 赤砂蛇凪浜 2016-05-13 17 58 12 ありがとうございます - modder 2016-06-03 22 27 41 modelは、jsonで指定するはずです。 - pppp 2017-08-30 06 55 39 こちらのチュートリアルは1.7.10版のものです。jsonで指定するのは1.8版以降ですので、まだチュートリアルには記載しておりません。今後1.12版の方はチュートリアル実装予定です。 - TomKate 2017-08-30 18 22 14 名前
https://w.atwiki.jp/widget/pages/11.html
?xmlversion= 1.0 encoding= { .konファイルのエンコーディング } ? XML宣言では、どのようなXMLおよびエンコーディングを使用しているのかをパーサに通知します。 XMLdeclaration which tells theparserwhat kind of XML and encoding itisreading. widget Widgetコードを開始する必須タグ Mandatory tag which starts theWidgetcode. debug デバッグウィンドウのon/offを切り替える Turns the debug window on andoff,as well as givingoptionsfor how and when the debug is displayed. version Widgetのバージョン Defines the version oftheWidget. minimumVersion Widgetが使用可能なエンジンのバージョン Defines the version ofKonfabulatorthat theWidgetrequires to be able to run. window Widgetのサイズを決める必須のタグ。Windowの外側は一切表示されない。 Mandatory tag which defines how largetodraw theWidget.Anything outside the window bounds will be cut off. name Windowの名前を定義する。これは後でJavascripが処理するときに使います。Definesthewindow s name. Used for later manipulationinJavaScript. title Windowのタイトルを定義します。右クリックしたときなどのWidgetの名前としても使用されます。 Defines the window s title.Usedincontrol/right-clickfor displaying the Widget s name to the user (About title ) andinother areas. height Windowの高さをピクセル数で指定します。 Defines the window sheightin pixels. width Windowの幅をピクセル数で指定します。 Defines the window s widthinpixels. visible Widgetの可視・不可視をboolean値(0/1ortrue/false)で記述します。これは、あるデータを取得したりユーザが操作する前に何らかの処理を組み込む場合に有効です。 A boolean value (1 or 0, true or falsecanbe used in substitute) which defines whether the Widget can be seenornot. This is useful if you need tofetchsomedataor run a couple of short processes before displaying the Widgetto theuser. image Allows use of images in a Widget. name Defines the image s name. Used forlatermanipulationinJavaScript. hOffset Defines how many pixels to offsettheimagehorizontallyfrom the window s top-left corner. vOffset Defines how many pixels to offsettheimageverticallyfrom the window s top-left corner. hRegistrationPoint Defines the X-pixel coordinatefromwhichtobase things like offset and rotation. This is set to 0 by default (The left side of the image). vRegistrationPoint Defines the Y-pixel coordinatefromwhichtobase things like offset and rotation. This is set to 0 by default (The top edge of the image). rotation Defines how far to rotate an image indegrees. opacity A value from 0 to 255 which defines theopacityoftheimage. Percentile values can also be used. onMouseDown Used to define what happens themousebuttonispressed on the image object. onMouseUp Used to define what happens themousebuttonisreleased on the image object. This is favored over the onMouseDown action. text Allows use of text in a Widget. name Defines the text s name. Used forlatermanipulationinJavaScript. data Defines what the text says. hOffset Defines how many pixels to offsetthetexthorizontallyfrom the window s top-left corner. Affected by the alignment tag. vOffset Defines how many pixels to offsetthetextverticallyfrom the window s top-left corner. Uses the text s baseline for offset as opposed to the top edge. alignment Values of left , center , and right areusedhereto define where the text draws from. color Defines the color of the text inahexadecimalvalue(examples #000000 is black, #8000FF is violet, #FFFFFF is white). font Defines the font used in the text. size The font size in point units. opacity A value from 0 to 255 which defines the opacityofthetext. Percentile values can also be used. onMouseDown Used to define what happens the mousebuttonispressed on the text object. onMouseUp Used to define what happens the mousebuttonisreleased on the text object. This is favored over the onMouseDown action. textarea Allows use of text input in a Widget. name Defines the textarea s name. Used forlatermanipulationin JavaScript. hOffset Defines how many pixels to offsettheinputhorizontally from the window s top-left corner. Affected by the alignment tag. vOffset Defines how many pixels to offset theinputverticallyfrom the window s top-left corner. Uses the text s baseline for offset as opposed to the top edge. lines Used to define how many lines are displayedatatime. columns Defines how wide to make the text inputbeforemoretext would cause the input to scroll. color Defines the color of the text in ahexadecimalvalue(examples #000000 is black, #8000FF is violet, #FFFFFF is white). font Defines the font used in the input. bgColor Defines the color of the input backgroundinahexadecimal value (examples #000000 is black, #8000ff is violet, #ffffff is white). bgopacity A value from 0 to 255 which defines theopacityofthe input background. Percentile values can also be used. onKeyPress Used to define what happens each time akeyispressed. action trigger= (Some event here) Lets events happenwhentheWidget is first loaded, when it is focused, after the computer is awaken from sleep, when itspreferencesarechanged, and more. Can be used multiple times for different events! about-box Works like the src tag in an imageobject,butfor an about box. Use multiple to have multiple about boxes. Examine The Weather.kon in your text editor and look at thedifferenttagsused to get an idea of what kinds of objects are immediately available for usewhenyouwrite a Widget. When you are done, close The Weather.kon . There are many, many more tags than are listed here! PleasechecktheKonfabulator Reference Manual for other objects, attributes, and action triggers if you want tofindoutmore of what a Widget can display and do.
https://w.atwiki.jp/akasatanahama/pages/64.html
概要 メタデータを使用し、一つのIDで複数のアイテムを追加したり、色違いのアイテムを追加したりする。 ソースコード AluminiumMod.java package tutorial.aluminiummod; import net.minecraft.item.Item; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; @Mod(modid = AluminiumMod.MODID, name = AluminiumMod.MODNAME, version = AluminiumMod.VERSION) public class AluminiumMod { public static final String MODID = "AluminiumMod"; public static final String MODNAME = "Aluminium Mod"; public static final String VERSION = "1.0.0"; public static Item aluminiumColored; @EventHandler public void perInit(FMLPreInitializationEvent event) { //ここは通常のアイテムと同様。 aluminiumColored = new ColoredAluminium() .setUnlocalizedName("auminiumColored") .setTextureName("aluminiummod colored_aluminium"); GameRegistry.registerItem(aluminiumColored, "auminiumColored"); } } ColoredAluminium.java package tutorial.aluminiummod; import java.util.List; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class ColoredAluminium extends Item { private IIcon[] iicon = new IIcon[16]; public ColoredAluminium () { super (); this.setCreativeTab(CreativeTabs.tabMaterials); this.setMaxDamage(0); this.setHasSubtypes(true); } @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister iicon) { for (int i = 0; i 16; i ++) { this.iicon[i] = iicon.registerIcon(this.getIconString() + "." + i); } } @Override @SideOnly(Side.CLIENT) public IIcon getIconFromDamage(int meta) { return iicon[meta]; } @Override @SideOnly(Side.CLIENT) public void getSubItems(Item item, CreativeTabs creativeTab, List list) { for (int i = 0; i 16; i ++) { list.add(new ItemStack(this, 1, i)); } } @Override public int getMetadata(int meta) { return meta; } @Override public String getUnlocalizedName(ItemStack itemStack) { return super.getUnlocalizedName() + "." + itemStack.getItemDamage(); } } 解説 Item Item setMaxDamage(int meta) メタデータの最高値を設定する。 Item setHasSubtypes(boolean flag) メタデータの使い方によって引数を変える。 ツールなどのようにダメージ値として使うときはfalseを、 このチュートリアルのように複数のアイテムのようにして使うときはtrueを渡す。 void registerIcons(IIconRegister register) アイテムのテクスチャを指定するメソッド。 引数のIIconRegisterを使用し、registerIconで初期化する。 IIcon getIconFromDamage(int meta) 引数のメタデータを基にIIconを返す。 描画時に呼ばれる。 void getSubItems(Item item, CreativeTabs creativeTab, List list) クリエイティブタブにアイテムを登録するメソッド。 第三引数のListにアイテムスタックを追加する。 int getMetadata(int meta) メタデータを返す。 引数をそのまま返せばいい。 String getUnlocalizedName(ItemStack itemStack) アイテムのlangファイルに指定するための文字列を返すメソッド。 引数のItemStackからダメージ値を取得し、反映すればよい。 IIcon アイテム・ブロックのアイコンを保持しておくインターフェース。 IIconRegister IIconを設定するためのインターフェース。 IIcon registerIcon(String name) IIconRegisterの唯一のメソッド。 テクスチャ名を渡せば対応したIIconが得られる。 SideOnly Side value メソッド・フィールド・クラスなどにつけられるアノテーション。 クライアント/サーバーの指定した側のみで認識されるようになる。 フィールドにつけるとマルチではクラッシュすることがある。 そのため、メソッドにつけるのみにしておいた方がよい。 Side SideOnlyで使用するenum。 CLIENTとSERVERが定義されている。 使用例 各種中間素材を追加している部分。 +オファレンMOD OfalenModCore.java package nahama.ofalenmod; /*略*/ /**@author Akasata Nahama*/ @Mod(modid = OfalenModCore.MODID, name = OfalenModCore.MODNAME, version = OfalenModCore.VERSION) public class OfalenModCore { public static final String MODID = "OfalenMod"; public static final String MODNAME = "Ofalen Mod"; public static final String VERSION = "[1.7.10]1.0.0"; /*略*/ /**最初に行われる処理。アイテム・ブロックの追加などを行う*/ @EventHandler public void preInit(FMLPreInitializationEvent event) { /*略*/ //アイテムを設定するメソッドを実行 OfalenModItemCore.registerItem(); /*略*/ } /*略*/ } OfalenModItemCore.java package nahama.ofalenmod.core; /*略*/ public class OfalenModItemCore { //アイテムの定義 /*略*/ /**0 Machine Cover Plate, 1 Grade 3 Part, 2 Lump of Stone, 3 Stone Fuel, 4 Ofalen Fuel, 5 Laser Magazine*/ public static Item partsOfalen; /*略*/ /**アイテムを設定する*/ public static void registerItem () { /*略*/ partsOfalen = new Parts(6) .setUnlocalizedName("partsOfalen") .setTextureName("ofalenmod parts"); GameRegistry.registerItem(partsOfalen, "partsOfalen"); /*略*/ } } Parts.java package nahama.ofalenmod.item; import java.util.List; import nahama.ofalenmod.OfalenModCore; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class Parts extends Item { protected IIcon[] iicon; private final int type; public Parts (int type) { super (); this.type = type; this.setCreativeTab(OfalenModCore.tabOfalen); this.setHasSubtypes(true); this.setMaxDamage(0); } /**メタデータ違いのテクスチャを登録する*/ @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister register) { this.iicon = new IIcon[type]; for (int i = 0; i type; i ++) { this.iicon[i] = register.registerIcon(this.getIconString() + "-" + i); } } /**メタデータにより返すIIconを変える*/ @Override @SideOnly(Side.CLIENT) public IIcon getIconFromDamage(int meta) { return iicon[meta]; } /**メタデータ違いのアイテムを登録する*/ @Override @SideOnly(Side.CLIENT) public void getSubItems(Item item, CreativeTabs creativeTab, List list) { for (int i = 0; i type; i ++) { list.add(new ItemStack(this, 1, i)); } } /**メタデータを返す*/ @Override public int getMetadata(int meta) { return meta; } /**メタデータにより内部名を変える*/ @Override public String getUnlocalizedName(ItemStack itemStack) { return this.getUnlocalizedName() + "." + itemStack.getItemDamage(); } } コメント この項目に関する質問などをどうぞ。 とても参考になりました。これからもこのサイトの更新頑張ってください。 - 名無しさん 2016-04-23 14 00 54 ありがとうございます。チュートリアルの更新があまりできていなくて申し訳ないです。できる限り頑張りますので、今後もよろしくお願いします。 - 赤砂蛇凪浜 2016-04-24 20 19 29 この会話はコメント/MOD製作チュートリアル/メタデータを持つブロックの追加に移動しました。 このページのソースの大半が読めなくなっていますが、何かあったのでしょうか? - 名無しさん 2017-08-02 18 42 25 ご迷惑をおかけしております。@wikiのプラグインの不具合と思われます。トップページのお知らせを更新しましたので、ご覧ください。 - 赤砂蛇凪浜 2017-08-03 11 57 26 名前
https://w.atwiki.jp/akasatanahama/pages/103.html
概要 新しく苗木・原木・葉を追加し、苗木が育ったら木が生成されるようにする。 今回は一つのIDで一種類の木しか追加していないが、バニラの木のようにメタデータを利用して何種類かの木を追加することも可能。 ※5/22更新 葉のテクスチャの指定ができていなかったため、追記・修正しました。 テクスチャは、sapling_aluminium,log_aluminium_top,log_aluminium_side,leaves_aluminium,leaves_aluminium_opaqueでそれぞれ指定できます。 ソースコード AluminiumMod.java package tutorial.aluminiummod; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; import net.minecraft.block.Block; import net.minecraftforge.oredict.OreDictionary; @Mod(modid = AluminiumMod.MODID, name = AluminiumMod.MODNAME, version = AluminiumMod.VERSION) public class AluminiumMod { public static final String MODID = "AluminiumMod"; public static final String MODNAME = "Aluminium Mod"; public static final String VERSION = "1.0.0"; public static Block saplingAluminium; public static Block logAluminium; public static Block leavesAluminium; @EventHandler public void perInit(FMLPreInitializationEvent event) { saplingAluminium = new BlockAluminiumSapling() .setBlockName("saplingAluminium") .setBlockTextureName("aluminiummod sapling_aluminium"); GameRegistry.registerBlock(saplingAluminium, "saplingAluminium"); OreDictionary.registerOre("saplingAluminium", saplingAluminium); logAluminium = new BlockAluminiumLog() .setBlockName("logAluminium") .setBlockTextureName("aluminiummod log_aluminium"); GameRegistry.registerBlock(logAluminium, "logAluminium"); OreDictionary.registerOre("logAluminium", logAluminium); leavesAluminium = new BlockAluminiumLeaves() .setBlockName("leavesAluminium") .setBlockTextureName("aluminiummod leaves_aluminium"); GameRegistry.registerBlock(leavesAluminium, ItemAluminiumLeaves.class, "leavesAluminium"); OreDictionary.registerOre("leavesAluminium", leavesAluminium); } } BlockAluminiumSapling.java +長いので囲みます package tutorial.aluminiummod; import static net.minecraftforge.common.EnumPlantType.*; import java.util.List; import java.util.Random; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockSapling; import net.minecraft.block.IGrowable; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraftforge.common.EnumPlantType; import net.minecraftforge.common.IPlantable; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.terraingen.TerrainGen; public class BlockAluminiumSapling extends BlockSapling implements IPlantable, IGrowable { public BlockAluminiumSapling() { super(); this.setCreativeTab(CreativeTabs.tabDecorations); this.setTickRandomly(true); this.setHardness(0F); this.setStepSound(soundTypeGrass); float f = 0.4F; this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); } @Override public boolean canPlaceBlockAt(World world, int x, int y, int z) { // Blockで上書き可能なブロックかどうかの判定をしているが、BlockBushでcanBlockStayの判定を追加している。 return world.getBlock(x, y, z).isReplaceable(world, x, y, z) this.canBlockStay(world, x, y, z); } @Override protected boolean canPlaceBlockOn(Block block) { // 草、土、耕された土ならtrueを返す。 return block == Blocks.grass || block == Blocks.dirt || block == Blocks.farmland; } @Override public void onNeighborBlockChange(World world, int x, int y, int z, Block block) { this.checkAndDropBlock(world, x, y, z); } @Override protected void checkAndDropBlock(World world, int x, int y, int z) { if (!this.canBlockStay(world, x, y, z)) { this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); world.setBlockToAir(x, y, z); } } @Override public boolean canBlockStay(World world, int x, int y, int z) { // 下のブロックのcanSustainPlantで判定している。 return world.getBlock(x, y - 1, z).canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, this); } @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { // 当たり判定を消すため、nullを返している。 return null; } @Override public boolean isOpaqueCube() { return false; } @Override public boolean renderAsNormalBlock() { return false; } @Override public int getRenderType() { return 1; } @Override public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) { return Plains; } @Override public Block getPlant(IBlockAccess world, int x, int y, int z) { return this; } @Override public int getPlantMetadata(IBlockAccess world, int x, int y, int z) { return world.getBlockMetadata(x, y, z); } @Override public void updateTick(World world, int x, int y, int z, Random random) { // サーバー側で、checkAndDropBlock・明るさの判定を行い、条件を満たしていれば1/7の確率で成長する。 if (!world.isRemote) { this.checkAndDropBlock(world, x, y, z); if (world.getBlockLightValue(x, y + 1, z) = 9 random.nextInt(7) == 0) { this.func_149879_c(world, x, y, z, random); } } } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { // Blockと同様。 return blockIcon; } @Override public void func_149879_c(World world, int x, int y, int z, Random random) { // 一度も成長していないなら一段階成長させ、二段階目なら木を生成する。 // 一段階目の成長が終わったかどうかは、メタデータの二進数四桁目で判断する。 int meta = world.getBlockMetadata(x, y, z); if ((meta 8) == 0) { world.setBlockMetadataWithNotify(x, y, z, meta | 8, 4); } else { this.func_149878_d(world, x, y, z, random); } } @Override public void func_149878_d(World world, int x, int y, int z, Random random) { // Eventを呼び出しているが、他MODでキャンセルされたくなければこの部分は削除してよい。 if (!TerrainGen.saplingGrowTree(world, random, x, y, z)) return; // メタデータを利用して複数種類の木を追加したい場合はバニラの苗木を参考にするとよい。 int meta = 0; // 大木を生成したい場合はこの部分を参考にするとよい。 // Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) new WorldGenTrees(true); Object object = new WorldGenAluminiumTrees(true); world.setBlock(x, y, z, Blocks.air, 0, 4); if (!((WorldGenerator) object).generate(world, random, x, y, z)) { world.setBlock(x, y, z, this, meta, 4); } } @Override public boolean func_149880_a(World world, int x, int y, int z, int type) { return world.getBlock(x, y, z) == this (world.getBlockMetadata(x, y, z) 7) == type; } @Override public int damageDropped(int meta) { // Blockと同様。 return 0; } @Override @SideOnly(Side.CLIENT) public void getSubBlocks(Item item, CreativeTabs tab, List list) { // Blockと同様。 list.add(new ItemStack(item, 1, 0)); } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister register) { // Blockと同様。 blockIcon = register.registerIcon(this.getTextureName()); } @Override public boolean func_149851_a(World world, int x, int y, int z, boolean isRemote) { return true; } @Override public boolean func_149852_a(World world, Random random, int x, int y, int z) { return world.rand.nextFloat() 0.45D; } @Override public void func_149853_b(World world, Random random, int x, int y, int z) { this.func_149879_c(world, x, y, z, random); } } WorldGenAluminiumTrees.java +長いので囲みます package tutorial.aluminiummod; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.BlockSapling; import net.minecraft.block.material.Material; import net.minecraft.init.Blocks; import net.minecraft.util.Direction; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraftforge.common.util.ForgeDirection; public class WorldGenAluminiumTrees extends WorldGenAbstractTree { private final int minTreeHeight; private final boolean vinesGrow; private final int metaWood; private final int metaLeaves; public WorldGenAluminiumTrees(boolean doBlockNotify) { this(doBlockNotify, 4, 0, 0, false); } public WorldGenAluminiumTrees(boolean doBlockNotify, int minTreeHeight, int metaWood, int metaLeaves, boolean vinesGrow) { super(doBlockNotify); this.minTreeHeight = minTreeHeight; this.metaWood = metaWood; this.metaLeaves = metaLeaves; this.vinesGrow = vinesGrow; } @Override public boolean generate(World world, Random random, int x, int y, int z) { int l = random.nextInt(3) + minTreeHeight; if (y 1 || y + l + 1 256) return false; byte b0; int k1; Block block; for (int iy = y; iy = y + 1 + l; ++iy) { b0 = 1; if (iy == y) { b0 = 0; } if (iy = y + 1 + l - 2) { b0 = 2; } for (int ix = x - b0; ix = x + b0; ++ix) { for (int iz = z - b0; iz = z + b0; ++iz) { if (iy 0 || iy = 256) return false; block = world.getBlock(ix, iy, iz); if (!this.isReplaceable(world, ix, iy, iz)) return false; } } } Block block2 = world.getBlock(x, y - 1, z); boolean isSoil = block2.canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, (BlockSapling) AluminiumMod.saplingAluminium); if (!isSoil || y = 256 - l - 1) return false; block2.onPlantGrow(world, x, y - 1, z, x, y, z); b0 = 3; byte b1 = 0; int l1; int i2; int j2; int i3; for (k1 = y - b0 + l; k1 = y + l; ++k1) { i3 = k1 - (y + l); l1 = b1 + 1 - i3 / 2; for (i2 = x - l1; i2 = x + l1; ++i2) { j2 = i2 - x; for (int k2 = z - l1; k2 = z + l1; ++k2) { int l2 = k2 - z; if (Math.abs(j2) != l1 || Math.abs(l2) != l1 || random.nextInt(2) != 0 i3 != 0) { Block block1 = world.getBlock(i2, k1, k2); if (block1.isAir(world, i2, k1, k2) || block1.isLeaves(world, i2, k1, k2)) { this.setBlockAndNotifyAdequately(world, i2, k1, k2, AluminiumMod.leavesAluminium, metaLeaves); } } } } } for (k1 = 0; k1 l; ++k1) { block = world.getBlock(x, y + k1, z); if (block.isAir(world, x, y + k1, z) || block.isLeaves(world, x, y + k1, z)) { setBlockAndNotifyAdequately(world, x, y + k1, z, AluminiumMod.logAluminium, metaWood); if (vinesGrow k1 0) { if (random.nextInt(3) 0 world.isAirBlock(x - 1, y + k1, z)) { this.setBlockAndNotifyAdequately(world, x - 1, y + k1, z, Blocks.vine, 8); } if (random.nextInt(3) 0 world.isAirBlock(x + 1, y + k1, z)) { this.setBlockAndNotifyAdequately(world, x + 1, y + k1, z, Blocks.vine, 2); } if (random.nextInt(3) 0 world.isAirBlock(x, y + k1, z - 1)) { this.setBlockAndNotifyAdequately(world, x, y + k1, z - 1, Blocks.vine, 1); } if (random.nextInt(3) 0 world.isAirBlock(x, y + k1, z + 1)) { this.setBlockAndNotifyAdequately(world, x, y + k1, z + 1, Blocks.vine, 4); } } } } if (vinesGrow) { for (k1 = y - 3 + l; k1 = y + l; ++k1) { i3 = k1 - (y + l); l1 = 2 - i3 / 2; for (i2 = x - l1; i2 = x + l1; ++i2) { for (j2 = z - l1; j2 = z + l1; ++j2) { if (world.getBlock(i2, k1, j2).isLeaves(world, i2, k1, j2)) { if (random.nextInt(4) == 0 world.getBlock(i2 - 1, k1, j2).isAir(world, i2 - 1, k1, j2)) { this.growVines(world, i2 - 1, k1, j2, 8); } if (random.nextInt(4) == 0 world.getBlock(i2 + 1, k1, j2).isAir(world, i2 + 1, k1, j2)) { this.growVines(world, i2 + 1, k1, j2, 2); } if (random.nextInt(4) == 0 world.getBlock(i2, k1, j2 - 1).isAir(world, i2, k1, j2 - 1)) { this.growVines(world, i2, k1, j2 - 1, 1); } if (random.nextInt(4) == 0 world.getBlock(i2, k1, j2 + 1).isAir(world, i2, k1, j2 + 1)) { this.growVines(world, i2, k1, j2 + 1, 4); } } } } } if (random.nextInt(5) == 0 l 5) { for (k1 = 0; k1 2; ++k1) { for (i3 = 0; i3 4; ++i3) { if (random.nextInt(4 - k1) == 0) { l1 = random.nextInt(3); this.setBlockAndNotifyAdequately(world, x + Direction.offsetX[Direction.rotateOpposite[i3]], y + l - 5 + k1, z + Direction.offsetZ[Direction.rotateOpposite[i3]], Blocks.cocoa, l1 2 | i3); } } } } } return true; } @Override protected boolean isReplaceable(World world, int x, int y, int z) { Block block = world.getBlock(x, y, z); return block.isAir(world, x, y, z) || block.isLeaves(world, x, y, z) || block.isWood(world, x, y, z) || this.func_150523_a(block); } @Override protected boolean func_150523_a(Block block) { return block.getMaterial() == Material.air || block.getMaterial() == Material.leaves || block == Blocks.grass || block == Blocks.dirt || block == Blocks.log || block == Blocks.log2 || block == Blocks.sapling || block == Blocks.vine; } private void growVines(World world, int x, int y, int z, int length) { this.setBlockAndNotifyAdequately(world, x, y, z, Blocks.vine, length); int i1 = 4; while (true) { --y; if (!world.getBlock(x, y, z).isAir(world, x, y, z) || i1 = 0) { return; } this.setBlockAndNotifyAdequately(world, x, y, z, Blocks.vine, length); --i1; } } } BlockAluminiumLog.java +長いので囲みます package tutorial.aluminiummod; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockLog; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class BlockAluminiumLog extends BlockLog { private IIcon[] iicon = new IIcon[2]; public BlockAluminiumLog() { super(); this.setCreativeTab(CreativeTabs.tabBlock); this.setHardness(2.0F); this.setStepSound(soundTypeWood); } @Override public int getRenderType() { return 31; } @Override public int onBlockPlaced(World world, int x, int y, int z, int side, float posX, float posY, float posZ, int meta) { // 設置された方向に応じてメタデータを設定する。 int metaType = meta 3; byte direction = 0; switch (side) { case 0 case 1 direction = 0; break; case 2 case 3 direction = 8; break; case 4 case 5 direction = 4; } return metaType | direction; } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { int k = meta 12; int l = meta 3; return k == 0 (side == 1 || side == 0) ? this.getTopIcon(l) (k == 4 (side == 5 || side == 4) ? this.getTopIcon(l) (k == 8 (side == 2 || side == 3) ? this.getTopIcon(l) this.getSideIcon(l))); } @Override public int damageDropped(int meta) { return meta 3; } @Override @SideOnly(Side.CLIENT) protected IIcon getSideIcon(int meta) { return this.iicon[1]; } @Override @SideOnly(Side.CLIENT) protected IIcon getTopIcon(int meta) { return this.iicon[0]; } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iicon) { this.iicon[0] = iicon.registerIcon(this.getTextureName() + "_top"); this.iicon[1] = iicon.registerIcon(this.getTextureName() + "_side"); } @Override protected ItemStack createStackedBlock(int meta) { return new ItemStack(Item.getItemFromBlock(this), 1, meta 3); } @Override public void breakBlock(World world, int x, int y, int z, Block block, int meta) { // 周囲の葉ブロックの消滅を始める。 byte b0 = 4; int i1 = b0 + 1; if (!world.checkChunksExist(x - i1, y - i1, z - i1, x + i1, y + i1, z + i1)) return; for (int ix = -b0; ix = b0; ++ix) { for (int iy = -b0; iy = b0; ++iy) { for (int iz = -b0; iz = b0; ++iz) { Block block1 = world.getBlock(x + ix, y + iy, z + iz); if (block1.isLeaves(world, x + ix, y + iy, z + iz)) { block1.beginLeavesDecay(world, x + ix, y + iy, z + iz); } } } } } @Override public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) { return true; } @Override public boolean isWood(IBlockAccess world, int x, int y, int z) { return true; } } BlockAluminiumLeaves.java +長いので囲みます package tutorial.aluminiummod; import java.util.ArrayList; import java.util.Random; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.ColorizerFoliage; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.IShearable; public class BlockAluminiumLeaves extends BlockLeaves implements IShearable { protected boolean isFancy; protected IIcon[] iicon = new IIcon[2]; int[] array; public BlockAluminiumLeaves() { super(); this.setTickRandomly(true); this.setCreativeTab(CreativeTabs.tabDecorations); this.setHardness(0.2F); this.setLightOpacity(1); this.setStepSound(soundTypeGrass); } @Override @SideOnly(Side.CLIENT) public int getBlockColor() { double d0 = 0.5D; double d1 = 1.0D; return ColorizerFoliage.getFoliageColor(d0, d1); } @Override @SideOnly(Side.CLIENT) public int getRenderColor(int color) { return ColorizerFoliage.getFoliageColorBasic(); } @Override @SideOnly(Side.CLIENT) public int colorMultiplier(IBlockAccess iBlockAccess, int x, int y, int z) { // バイオームの境目である程度スムーズになるよう、周囲9ブロックのバイオームから平均を求めている。 int ir = 0; int ig = 0; int ib = 0; for (int iz = -1; iz = 1; ++iz) { for (int ix = -1; ix = 1; ++ix) { int color = iBlockAccess.getBiomeGenForCoords(x + ix, z + iz).getBiomeFoliageColor(x + ix, y, z + iz); ir += (color 16711680) 16; ig += (color 65280) 8; ib += color 255; } } return (ir / 9 255) 16 | (ig / 9 255) 8 | ib / 9 255; } @Override public void breakBlock(World world, int x, int y, int z, Block block, int meta) { // 周囲の葉ブロックの消滅を始める。 byte b0 = 1; int i1 = b0 + 1; if (world.checkChunksExist(x - i1, y - i1, z - i1, x + i1, y + i1, z + i1)) { for (int j1 = -b0; j1 = b0; ++j1) { for (int k1 = -b0; k1 = b0; ++k1) { for (int l1 = -b0; l1 = b0; ++l1) { Block block1 = world.getBlock(x + j1, y + k1, z + l1); if (block1.isLeaves(world, x + j1, y + k1, z + l1)) { block1.beginLeavesDecay(world, x + j1, y + k1, z + l1); } } } } } } @Override public void updateTick(World world, int x, int y, int z, Random random) { if (world.isRemote) return; int meta = world.getBlockMetadata(x, y, z); // メタデータの二進数四桁目が0(周囲で原木/葉が破壊されていない)か、 // 三桁目が0以外(プレイヤーに設置されたもの)なら消滅させない。 if ((meta 8) == 0 || (meta 4) != 0) return; // 周囲のブロックを調査し、葉の消滅を抑えるブロック(原木)がなければ消滅させる。 byte b4 = 4; int i5 = b4 + 1; byte b32 = 32; int i1024 = b32 * b32; int i16 = b32 / 2; if (array == null) { array = new int[b32 * b32 * b32]; } int l1; if (world.checkChunksExist(x - i5, y - i5, z - i5, x + i5, y + i5, z + i5)) { for (int ix = -b4; ix = b4; ++ix) { for (int iy = -b4; iy = b4; ++iy) { for (int iz = -b4; iz = b4; ++iz) { Block block = world.getBlock(x + ix, y + iy, z + iz); if (!block.canSustainLeaves(world, x + ix, y + iy, z + iz)) { if (block.isLeaves(world, x + ix, y + iy, z + iz)) { array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16] = -2; } else { array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16] = -1; } } else { array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16] = 0; } } } } for (l1 = 1; l1 = 4; ++l1) { for (int ix = -b4; ix = b4; ++ix) { for (int iy = -b4; iy = b4; ++iy) { for (int iz = -b4; iz = b4; ++iz) { if (array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16] == l1 - 1) { if (array[(ix + i16 - 1) * i1024 + (iy + i16) * b32 + iz + i16] == -2) { array[(ix + i16 - 1) * i1024 + (iy + i16) * b32 + iz + i16] = l1; } if (array[(ix + i16 + 1) * i1024 + (iy + i16) * b32 + iz + i16] == -2) { array[(ix + i16 + 1) * i1024 + (iy + i16) * b32 + iz + i16] = l1; } if (array[(ix + i16) * i1024 + (iy + i16 - 1) * b32 + iz + i16] == -2) { array[(ix + i16) * i1024 + (iy + i16 - 1) * b32 + iz + i16] = l1; } if (array[(ix + i16) * i1024 + (iy + i16 + 1) * b32 + iz + i16] == -2) { array[(ix + i16) * i1024 + (iy + i16 + 1) * b32 + iz + i16] = l1; } if (array[(ix + i16) * i1024 + (iy + i16) * b32 + (iz + i16 - 1)] == -2) { array[(ix + i16) * i1024 + (iy + i16) * b32 + (iz + i16 - 1)] = l1; } if (array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16 + 1] == -2) { array[(ix + i16) * i1024 + (iy + i16) * b32 + iz + i16 + 1] = l1; } } } } } } } l1 = array[i16 * i1024 + i16 * b32 + i16]; if (l1 = 0) { world.setBlockMetadataWithNotify(x, y, z, meta 7, 4); } else { this.removeLeaves(world, x, y, z); } } @Override @SideOnly(Side.CLIENT) public void randomDisplayTick(World world, int x, int y, int z, Random random) { // 水を滴らせる? if (world.canLightningStrikeAt(x, y + 1, z) !World.doesBlockHaveSolidTopSurface(world, x, y - 1, z) random.nextInt(15) == 1) { double dx = x + random.nextFloat(); double dy = y - 0.05D; double dz = z + random.nextFloat(); world.spawnParticle("dripWater", dx, dy, dz, 0.0D, 0.0D, 0.0D); } } private void removeLeaves(World world, int x, int y, int z) { // ドロップさせ、空気ブロックに置き換える。 this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); world.setBlockToAir(x, y, z); } @Override public int quantityDropped(Random random) { return random.nextInt(20) == 0 ? 1 0; } @Override public Item getItemDropped(int meta, Random random, int fortune) { return Item.getItemFromBlock(AluminiumMod.saplingAluminium); } @Override public void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float chance, int par7) { super.dropBlockAsItemWithChance(world, x, y, z, meta, 1.0f, par7); } @Override protected void func_150124_c(World world, int x, int y, int z, int meta, int chance) {} @Override protected int func_150123_b(int meta) { return 20; } @Override public boolean isOpaqueCube() { return !isFancy; } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { return iicon[isFancy ? 0 1]; } @Override @SideOnly(Side.CLIENT) public void setGraphicsLevel(boolean isFancy) { this.isFancy = isFancy; } @Override protected ItemStack createStackedBlock(int meta) { return new ItemStack(Item.getItemFromBlock(this), 1, 0); } @Override public String[] func_150125_e() { return null; } @Override @SideOnly(Side.CLIENT) public boolean shouldSideBeRendered(IBlockAccess iBlockAccess, int x, int y, int z, int side) { Block block = iBlockAccess.getBlock(x, y, z); // 処理優先で隣が同じブロックだったらfalse。 return !isFancy block == this ? false super.shouldSideBeRendered(iBlockAccess, x, y, z, side); } @Override public boolean isShearable(ItemStack item, IBlockAccess world, int x, int y, int z) { return true; } @Override public ArrayList ItemStack onSheared(ItemStack item, IBlockAccess world, int x, int y, int z, int fortune) { ArrayList ItemStack ret = new ArrayList ItemStack (); ret.add(new ItemStack(this, 1, world.getBlockMetadata(x, y, z) 3)); return ret; } @Override public void beginLeavesDecay(World world, int x, int y, int z) { int meta = world.getBlockMetadata(x, y, z); if ((meta 8) == 0) { world.setBlockMetadataWithNotify(x, y, z, meta | 8, 4); } world.setBlockMetadataWithNotify(x, y, z, world.getBlockMetadata(x, y, z) | 8, 4); } @Override public boolean isLeaves(IBlockAccess world, int x, int y, int z) { return true; } @Override public ArrayList ItemStack getDrops(World world, int x, int y, int z, int meta, int fortune) { ArrayList ItemStack ret = new ArrayList ItemStack (); int chance = this.func_150123_b(meta); if (fortune 0) { chance -= 2 fortune; if (chance 10) chance = 10; } if (world.rand.nextInt(chance) == 0) ret.add(new ItemStack(this.getItemDropped(meta, world.rand, fortune), 1, this.damageDropped(meta))); chance = 200; if (fortune 0) { chance -= 10 fortune; if (chance 40) chance = 40; } this.captureDrops(true); this.func_150124_c(world, x, y, z, meta, chance); ret.addAll(this.captureDrops(false)); return ret; } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister register) { iicon[0] = register.registerIcon(this.getTextureName()); iicon[1] = register.registerIcon(this.getTextureName() + "_opaque"); } } ItemAluminiumLeaves.java package tutorial.aluminiummod; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; import net.minecraft.item.ItemLeaves; import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; public class ItemAluminiumLeaves extends ItemLeaves { protected final Block leaves; public ItemAluminiumLeaves(Block block) { super((BlockLeaves) block); this.leaves = block; this.setMaxDamage(0); this.setHasSubtypes(true); } @Override public int getMetadata(int meta) { // 設置時は二進数三桁目が1になる。 return meta | 4; } @Override public String getUnlocalizedName(ItemStack itemStack) { return leaves.getUnlocalizedName(); } @Override @SideOnly(Side.CLIENT) public IIcon getIconFromDamage(int meta) { return leaves.getIcon(0, meta); } @Override @SideOnly(Side.CLIENT) public int getColorFromItemStack(ItemStack itemStack, int pass) { return leaves.getRenderColor(itemStack.getItemDamage()); } } 解説 Block +長いので囲みます Block setTickRandomly(boolean needsRandomTick) trueに設定すると、ランダムでupdateTickが呼ばれるようになる。 植物の成長判定や葉の消滅などに使う。 void setBlockBounds(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) ブロックの大きさを設定する。 カーソルがあったかどうかの判定や、合わせたときの枠線の描画に使われる。 boolean canPlaceBlockAt(World world, int x, int y, int z) ブロックを設置できるかを判定する。 void onNeighborBlockChange(World world, int x, int y, int z, Block block) 隣接するブロックが更新された時の処理。 boolean canBlockStay(World world, int x, int y, int z) ブロックがとどまれるかどうか。 AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) 当たり判定を返す。 BlockではAxisAlignedBB.getBoundingBox(x + minX, y + minY, z + minZ, x + maxX, y + maxY, z + maxZ)を返している。 このメソッドをオーバーライドすれば当たり判定を変更できる。 boolean isOpaqueCube() 不透明なブロックかどうかを返す。 boolean renderAsNormalBlock() 通常のブロックのように描画するかどうかを返す。 柵や壁がつながるかどうかの判定にも使われる。 int getRenderType() レンダ―タイプを返す。 通常は0。 苗木や花、キノコなどは1。 原木、干草の俵などは31。 1を返すとTileEntityの設定などが適用される。 void updateTick(World world, int x, int y, int z, Random random) ブロックのアップデート時の処理。 needsRandomTickがtrueの時はランダムに呼ばれる。 falseだと何tick後に呼び出すなどの処理が可能。 int onBlockPlaced(World world, int x, int y, int z, int side, float posX, float posY, float posZ, int meta) ブロックが設置された時の処理。 ItemStack createStackedBlock(int meta) メタデータを反映してItemStackを生成し返す。 void breakBlock(World world, int x, int y, int z, Block block, int meta) ブロックが破壊された時の処理。 boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) 葉を維持させられるブロックかどうかを返す。 boolean isWood(IBlockAccess world, int x, int y, int z) 原木かどうかを返す。 木の生成時の判定に使う。 Block setLightOpacity(int lightOpacity) 光の透過度を設定する。 0で不透過。1で完全に透過。 int getBlockColor() ブロックの色を返す。 int getRenderColor(int color) 描画するときの色を返す。 インベントリ内での描画などに使う。 int colorMultiplier(IBlockAccess iBlockAccess, int x, int y, int z) ブロックを描画するときの色の係数を返す。 void randomDisplayTick(World world, int x, int y, int z, Random random) クライアントで描画されるときにランダムで呼ばれる。 int quantityDropped(Random random) ドロップ数を返す。 Item getItemDropped(int meta, Random random, int fortune) ドロップするアイテムを返す。 void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float chance, int par7) ブロックをドロップさせる。 boolean shouldSideBeRendered(IBlockAccess iBlockAccess, int x, int y, int z, int side) 引数の面を描画するかどうか。 引数の座標はメソッドを呼ばれたブロックではなく、その隣にあるブロック。 Blockでは、ブロックの大きさが通常より小さいでないか、引数の座標のブロックが不透明でないならtrueを返す。 void beginLeavesDecay(World world, int x, int y, int z) 葉の消滅を始める。 boolean isLeaves(IBlockAccess world, int x, int y, int z) 葉かどうかを返す。 ArrayList ItemStack getDrops(World world, int x, int y, int z, int meta, int fortune) ドロップアイテムのリストを返す。 BlockBush boolean canPlaceBlockOn(Block block) 引数のブロックの上に設置が可能かどうか。 void checkAndDropBlock(World world, int x, int y, int z) 設置されている状況が保てるかどうか判定し、保てないならドロップさせる。 BlockSapling void func_149879_c(World world, int x, int y, int z, Random random) 苗木を成長させる処理。 void func_149878_d(World world, int x, int y, int z, Random random) 木を生成する処理。 boolean func_149880_a(World world, int x, int y, int z, int type) 引数の座標のブロックが同じ種類の苗木かどうか。 ダークオーク・松などの生成に使っている。 EnumPlantType 植物の植え方を表すenum。 Plains 苗木や草、花など。 草・土・耕された土に植えられる。 ForgeDirection 方向を表すenum。 UP 上方向。 AxisAlignedBB ブロックの当たり判定などを保持するクラス。 TerrainGen 生成に関するEventを呼び出すクラス。 saplingGrowTree SaplingGrowTreeEventを呼び出す。 IPlantable 植物のインターフェース。 EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) 植物の植え方によってenumを返す。 Block getPlant(IBlockAccess world, int x, int y, int z) 引数の座標にある植物を返す。 基本的にはthisでよい。 int getPlantMetadata(IBlockAccess world, int x, int y, int z) 植物のメタデータを返す。 IGrowable 骨粉が使用できるブロックのインターフェース。 boolean func_149851_a(World world, int x, int y, int z, boolean isRemote) 骨粉が使用できるかどうかを返す。 boolean func_149852_a(World world, Random random, int x, int y, int z) 成長させるかどうかを返す。 void func_149853_b(World world, Random random, int x, int y, int z) 成長させる処理。 BlockRotatedPillar IIcon getSideIcon(int meta) 横の面のアイコンを返す。 IIcon getTopIcon(int meta) 上下面のアイコンを返す。 ColorizerFoliage 葉や草などの色を扱うクラス。 int getFoliageColor(double temperature, double humidity) 気温・湿度から色を生成して返す。 int getFoliageColorBasic() 基本の色を返す。 4764952(0x48A518, RGB (72,181,24))。 BlockLeaves void func_150124_c(World world, int x, int y, int z, int meta, int chance) リンゴのドロップに使うメソッド。 int func_150123_b(int meta) 苗木のドロップ確率を返す。 void setGraphicsLevel(boolean isFancy) 描画優先/処理優先の設定を反映する。 String[] func_150125_e() 木の種類名の配列を返す。 void removeLeaves(World world, int x, int y, int z) 引数の座標にあるブロックをドロップして破壊する。 privateなのでBlockAluminiumLeavesでは新しく実装していることになる。 IShearable ハサミで回収できるブロックのインターフェース。 boolean isShearable(ItemStack item, IBlockAccess world, int x, int y, int z) ハサミで回収できるかどうかを返す。 ArrayList ItemStack onSheared(ItemStack item, IBlockAccess world, int x, int y, int z, int fortune) ハサミで回収された時の処理。 ハサミで回収した時のドロップアイテムのリストを返す。 使用例 星の樹MODは木のカスタマイズ機能の影響で非常にわかりにくくなっているため、使用例は載せません。 Beta 1.0.0以前のコードは参考になるかもしれません。 コメント この項目に関する質問などをどうぞ。 左のメニューでTileEntityの追加を押すとこのページに来てしまいます。 - 名無しさん 2016-01-09 22 38 31 申し訳ありません。訂正いたしました。 - Tom Kate 2016-01-10 08 41 18 1.7.10で丸ごとコピーしてみたのですが、preInitのLeavesのところで落ちてしまいます。 - 名無しさん 2016-04-30 05 28 57 ご報告ありがとうございます。修正しました。 - 赤砂蛇凪浜 2016-04-30 16 13 34 葉のテクスチャは新しい文で指定する必要があるのでしょうか - 名無しさん 2016-05-20 16 43 05 テクスチャの指定に関する部分はいくつかあるため、どこについてなのかもう少し詳しくお願いします。 - 赤砂蛇凪浜 2016-05-20 17 28 58 葉のブロックのテクスチャ(描画設定で切り替わったり)です。例えばここのコードを丸ごと持ってきた場合、画像ファイルの名前や位置次第でテクスチャは表示されうるのでしょうか。すみません枝間違えました - ポン酢 2016-05-20 20 44 34 入力ミスのようですので、コメントは片方削除させていただきます。チュートリアルに不備があり、葉のテクスチャの指定がうまくできていなかったので修正しました。AluminiumMod.javaおよびBlockAluminiumLeaves.javaに変更がありますのでご確認ください。ご迷惑をおかけして申し訳ありませんでした。解説がわかりにくければ、またご質問いただけるとありがたいです。 - 赤砂蛇凪浜 2016-05-22 13 42 04 同じIDでいくつかの原木ブロックを追加するには、どのようにすれば良いのでしょうか。 - 名無しさん 2016-06-17 23 31 47 「メタデータを持つブロックの追加」に記載している方法で、getSubBlocksなどをオーバーライドしてテクスチャの指定を少し変更すればできます。ただし、原木の場合は向きをメタデータで記録しているので、一つのIDで追加できるのは4種類までです。バニラのコードや、(カスタム機能の影響で少しわかりにくくなっていますが)星の樹MODのソースコードも見てみてください。返信が遅くなってしまい、申し訳ありません。 - 赤砂蛇凪浜 2016-06-25 10 48 37 ありがとうございます! - 名無しさん 2016-06-25 21 53 03 返信するとこ間違えました... - 名無しさん 2016-06-25 21 53 43 このソースコードは1.10でも使用することができますか? - 名無しさん 2016-10-06 00 48 58 こちらのチュートリアルは記載の通り1.7.10版のものです。1.8以降は大きくコーディングが変更されておりますので使うことはできません。 - Tom Kate 2016-10-06 23 07 20 名前
https://w.atwiki.jp/ryoudan-trpg/pages/222.html
終了しました PL募集@3~5人 シナリオ ■ 小牙竜鬼 が潜む森 [LHTRPG基本ルールブック付属シナリオ] ●レギュレーション 基本ルルブのみを使用した、[CR1]のキャラクター3~5人を想定。 ★推奨キャラクター サンプルキャラクターを使用するクイックスタートの場合の推奨キャラクターは以下の通り。 PC1 鋼の守護者 PC2 白銀の聖者 PC3 闇に踊る影 PC4 焔の呼び手 PC5 流麗なる刃 ※パーティには最低一人ずつ、【アーキ職 戦士職 】と【アーキ職 回復職 】が居る事が望ましい。 ●状況の解説 PCの立場 PC達は全員 アキバ の街を拠点として活動する小規模ギルドに所属している。 ギルドに関してはPC達が自由に決めてよい。 又、想定以外の立場で参加する場合はGMに必ず相談して、許可を貰ってから行うこと。 開始時の状況 PC達のギルドが 円卓会議 からモンスター討伐の依頼を受けて大地人の暮らす、 ワラビ村 にやってきた所から始まる。 依頼と報酬 依頼は、 ワラビ村 の近郊に現れた 小牙竜鬼 達の討伐である。 依頼を完遂すれば、PCは一人当たり100Gを獲得できる。 PL希望欄 PL名/希望職業+参加可能曜日 水宗屋/バード (葵・トーリ http //lhrpg.com/lhz/sheets/026531.html)(7/31から一週間フリー8,9は18時、10は16時まで(昼間のみ)) パーティーバランス次第でキャラ変更します bottle/守護騎士(アデーレ・バルフェット http //lhrpg.com/lhz/sheets/020989.html ) (5日(火)以外なら全部大丈夫です) 蒼羽/吟遊詩人(Sarah http //lhrpg.com/lhz/sheets/024999.html) 6日(水)の10時以降のみ。0時や1時開始でいいなら候補増えますけど。 参加希望者コメント欄 bottle/守護騎士(アデーレ・バルフェット http //lhrpg.com/lhz/sheets/020989.html ) 月(夜)水・土・日曜日(昼夜)/7月27日より -- (bottle) 2014-07-27 03 26 05 蒼羽/吟遊詩人(Sarah http //lhrpg.com/lhz/sheets/024999.html)金は夕方以降、土は23時以降、日は夜以降可能。翌週は不明/7月28より -- (蒼羽) 2014-07-28 01 19 46 (アールグレイ http //lhrpg.com/lhz/pc_item?id=27290) 夜9時以降は参加可能、日曜は昼夜 -- (pokky/召喚術師) 2014-07-30 00 58 14 回復職として呼ばれました http //lhrpg.com/lhz/sheets/027718.html -- (アナグマ) 2014-08-03 23 28 35 名前 コメント すべてのコメントを見る
https://w.atwiki.jp/udk_tips/pages/24.html
概要 あなたがJavaやC++のようなプログラミング言語に詳しいなら、Unrealscriptを始めるのはそれほど難しくありません。 これは基本的に私が数年前に自分を見つけたところのそうです。しかしながら、私はいつもプログラミングに潜在的に関心を持っていました。 それで、道に沿って、私MelやMAYA Embedded Languageと、ActionScriptと、Javascriptと、C/C++でさえプログラムを作る方法を学びました。 しかしながら、私が最初にいつ開始したかを学ぶので、いろいろなことがどれくらい固かったかを一度も忘れたことがありません。 原文: http //okita.com/alex/?p=444 内容 コメント欄(誰でもコメントを残せます) 名前 コメント
https://w.atwiki.jp/outerzone/pages/158.html
地区はC-4。セントラル・ステーションの近場に構えるタワーマンション。 『…………。』 マンションの屋上。霊体化したエンタープライズは、周辺状況の監視を行っていた。 突如として引き起ったビッグアイ屋上の爆発を皮切りに、各地で多発したガラクシアの暴動。 事態は防衛隊が出動する程の騒動に発展し、パレードを楽しんでいた民衆も突然の事に混乱を極めている。 尤も、正しい判断ならば、後にパレードも中止・解散となると考えられるので、何事もなければ、事態も引くと見通していた。 当陣営というと、静観の姿勢であった。 この一連の騒動は、「示威運動(デモンストレーション)ではないか」という見解であった。 暴動が起きた場所は都市にとって主要なものとは言えず、人質を取るならまだしも行動自体に何の意味もない。 あまりに本格的な行動と感じられず、それまでの自爆テロの傾向を踏まえ、示威の類と見るのが妥当と思われた。 故に今回の暴動に関しても、"防衛隊の者に任せる"の総意で一致し、状況を静観しているのである。 『……他の者は来ていないようだな。』 周辺を監視している理由は、間近に見える距離に聳え立つビッグアイにもあった。 これほどのアクシデントともなれば、関心を抱いた他陣営がビルの下に集まるという可能性も否めない。 そうなれば、同C-4地区下に居る当陣営とも接触に発展することも十分あり得るのであった。 この同盟は、元から今夜は「行動しない」と決めていた。 「急いては事を仕損じる」というように、無暗矢鱈に動くことが良策と言えないからだ。 行く宛はないわけでもないが、わざわざ初日の未明や早朝にまで行くほどのものはなかったである。 一方で都市の中心部にある以上、逆に他陣営が来る可能性についてはある程度想定している。 他陣営を知る機会も兼ね、不利を悟って戦略的撤退に及ぶまでは、一先ずここを動かないつもりであった。 何にしても、今しばらくは状況を様子見する姿勢。 今日は一夜を明かすとし、理想としては本格的な行動開始を午前8時以降と決めていたのである。 『一先ずは、問題ないか。』 少なくとも、今の時間はまだ誰もこの地区には足を踏み入れていないと捉える。 エンタープライズも監視を終えると、主人達のいる部屋に向かい、屋上を通り抜けて中へと入った。 ☆ ☆ ☆ このマンションは、彼らの拠点の一つであった。 ここはジョースター不動産の管理下に置かれた建築物であり、その一室を所有している。 なお、彼らは用意した各地の拠点を転々と利用する予定なため、ここは半ば宿泊施設のような扱い。 「ギンてめえ!どういうことだッ!!」 エンタープライズが実体化して着いたのはマスターの声のする一階の部屋。 「なんでこいつが通らねーんだッ。ドロー2の後にドロー4!何の問題なくいけるじゃあねえかーーーーッ」 「違いますうぅ~。ドロー2の後にドロー4出すのはルール違反なんですぅー。ドロー2しか出せないんですぅ~~。」 「にゃにおぉ~~~~!?」 テーブルではジョセフと銀時の二人はUNOをしていた。 トーンは違うが、似たような声の二人が、UNOをするというシュールな光景であった。 銀時のマスターであるユウキは彼らのプレイに構いなしとエンタープライズの方を向き直った。 「あっ、おかえり!どうだった?」 「ああ、ただいま。敵はいなかったよ。」 親しげにユウキと接するエンタープライズ。 ユウキ達とは開始前から同盟を組んでいたのである。 ロールはハンターであるユウキ側にとって、本来ならば接点に乏しい陣営だった。 ただ、きっかけは一ヶ月前。"ユウキ宅がガラクシア派の自爆に巻き込まれる"というアクシデントに見舞われたこと。 (マスター特権で)代居を貰おうとジョースター不動産に足を踏み入れたことで以降、現在に至る。 「マスター達もいつまでゲームをやっているだ。これから方針会議なんだぞ。」 「今、片付けようって決めてたんだよッ!」 エンタープライズはジョセフと銀時へ注意を促した。 会議を始めようかという矢先に、ビッグアイの爆発が起きたため、中断された。 いないと分かればこの二名は放り出して遊び惚けてしまうので、世話の焼ける相手だった。 「まったく戦争は開始しているのだぞ。君達はいつまで気を抜けているんだ。」 「俺は別に気なんか緩んでねえぜ?ギンじゃああるまいに。」 「あァン?ジョジョテメー、何言い逃れようとしてんの?先にUNOやろうぜって言ってきたのはそっちだろか。」 溜息を吐く、エンタープライズ。 二人とも不真面目なため、聖杯戦争そっちのけでやり始める。 その点、"遊び呆けたやつだ"とエンタープライズも冷ややかな目を向けていた。 「……いいから、始めるぞ。」 エンタープライズはそう言いながら、ホワイトボードをテーブルの前に動かした。 ☆ ☆ ☆ パラディウム・シティの地図を磁石で挟まれたホワイトボード。 会議の進行役として、ホワイトボードの前に立つのはエンタープライズ。 他三名は、ホワイトボードに視点を置き、テーブルに腰掛ける形となっている。 ユウキは意欲的に見ているが、銀時はやる気なさげに鼻をほじっていた。 ジョセフも頬杖で見ている。ジョセフの横席には紙が挟まれたバインダーファイルが置かれていた。 「まず、当面の方針は、"聖杯戦争終結の為の同盟を結成させる"ことだ。」 エンタープライズはホワイトボードにも同様のことを書く。 「聖杯戦争を解決しないことには、主催側との本格的な対立には進めない。」 "黒幕の打倒"に当たるのが、ジョセフ達の目的。 しかし、主催にばかり目を向けたところで、動きを見せるわけもなく、他参加者を無視したところで、戦うのは必然。 まずは、聖杯戦争という本題をある程度解決し、主催側の動きを見せないことには、段階に入れないのである。 「とはいえ、武力行使だけで戦争が解決できるとは限らない。 極力だが、私達の手で他陣営との交渉を行っていき、同盟を形成しようと思う。」 ジョセフ側の考えとしては、「同盟を形成する」ということに至った。 「武力だけで、戦争は解決できるとは限らない」ことは、多くの戦いを経験したエンタープライズ自身がよく知っている。 交渉を取り、和平による停戦協定を結ぶ。そうした選択にこそ、時に戦争解決に繋がるわけだ。 「同盟って仲間を増やすの?」 「いや、仲間ではない。"聖杯の所存を決める"という目的に一致する同盟だ。」 ユウキは仲間かと疑問に感じたが、まだ仲間という気はなかった。 同盟とは一重に仲間を指すわけではない、"利害が一致から協力する"ことを同盟と呼ぶのである。 ジョセフ側とユウキ側は仲間という括りに入るものの、仲間として見るのは個人と場合次第なわけだ。 あくまで、当陣営における聖杯戦争の立ち位置は、「中立」であった。 戦うときは戦うが、戦わない時は戦わない。協力する時は協力するが、関与しない事は関与しない。 聖杯の所存も、"人と願いの結果次第"で他者に委ねることも基本的に構わないとしている。 咎めるべき「悪」と「害」さえ無ければ、個人的であれ、世界的であれ、あまり関与する必要はないからだ。 「10組や20組ならともかく、数は31組とあまりに多い。 さらに今後『ガラクシア』といったイレギュラーまで戦う必要はあるだろう。 そんな中、互いに何の決まりもない状態が続けば、まず事態は進展しない可能性も高い。」 「いつまでも戦い続けてもラチがあかねーぜ。」 同盟の理由には、「埒が明かなくなる」という点もある。 戦うならいざ知らず、29組をまともに相手するというのは途方もない話だ。 千日手に陥るのは、自分達だけではなく、参加者の誰にとってもメリットになり得ない。 「だからこそ、事態の進展の為にも折り合いを付けたい。 "聖杯の所存を決める"という目的の下に一致する同盟なのだ。」 「なるほど~。」 ユウキも同盟の在り方に納得した様子であった。 「二人もそれでいいだろうか?」 「うん!それがいいね。」 「まっ、面倒少なくていいからな。賛成だわ。」 「決まりだな。」 エンタープライズの問い掛けに、ユウキと銀時も方針に賛同し、ジョセフも確定と見た。 ユウキ達も最後まで戦うことが望みであり、何より考えの在り方と一致していた。 「ただ重要なのは、"聖杯を求める者達の決着はある程度の段階であること"と、 "聖杯を求めない者達の令呪破棄は最終であること"だ。 タイミングを見誤ってしまえば、それが付け入られる隙になってしまうからな。」 エンタープライズは付け加えて、"タイミング"を重要点として挙げた。 前者であれ、後者であれ、まずは同盟外の敵を倒すことが肝心となる。 相手にもその認識を持ってもらうことが、重要だと考えていた。 ☆ ☆ ☆ 「そのためにも、まず初めに「他陣営の把握」をする必要がある。」 ホワイトボードを消し、改めて同様のことを書いた。 「そうは言うけどよ~、手掛かりあんのか? この広い都市の中で、どうやって他所をみつけていくってんだ?」 銀時は、気だるい風に指摘する。 他陣営がどこ集まっているのか、目星がないことには動けない。 「バッチし……とまでは言えねーが、ヒントになるものならここにあるぜ。」 そうしてジョセフはバインダーファイルを銀時に渡す。ユウキも横見した。 それはちょうど、約一ヶ月半前。ジョセフやユウキが来た日から近日に至るが記載されている プリントには「氏名」「登録形態」「電話番号」と情報が羅列して記載した表であった。 「えっと、何これ?」 「それは、マスター達が来た時期に引っ越してきた者達をピックアップした顧客名簿だ。」 ジョセフやユウキを含め、マスターは基本的に「移住者」という設定で進んでいた。 支給された住居の中には「ジョースター不動産の管理に置かれている物件に引っ越した」という例も少なくない。 マスターであることを裏付ける証拠もないため、情報源としては今一つ確証に欠けるが、ヒントに結びつくものとなっていた。 「そして、これは開始前からの調査でわかったことだが……スクール街に複数のサーヴァントの反応が確認されていた。」 エンタープライズはホワイトボードに「スクール街」と書いた。 「出没の時間帯は、日中。密度の濃かった場所は、『アカデミー』や『月海原学園』だった。」 ホワイトボードに挟まれたマップ、『アカデミー』と『月海原学園』に赤丸を入れる。 エンタープライズにも「千里眼」に相当する効果を有しており、標的の捕捉には優れている。 加えて、両校では特に複数の陣営が密集していたことも相俟ってか、かなり存在感の高い地域となっていたのである。 「……ってことは、もしかして、マスターは"学生のロール"に多いってこと?」 「ああ、そうさ。サーヴァントの反応も、学生達の登下校に伴い、離散していた。 つまりは、学校関係者よりも"学生"に多いということだ。」 ユウキも名簿を見直すと、登録形態が"学生"の欄に黄色のマーカーペンで引かれていることに気付く。 「情報の傾向によると、マークライト街、スクール街、ストランド街などに見られる。」 エンタープライズも「スクール街」に加え、「マークライト街」、「ストランド街」と書いていく。 「特にその中でも多いのはマークライト街、さらに絞るなら……"B-3"から"C-3"だ。」 「マークライト街」に〇を囲み、下にB-3とC-3と書いていく。 スクール街やストランド街には住宅もあるものの、住居としては元より住宅街のマークライト街の方が多い。 また、マークライト街でもB-2やC-2になると物件は少なくなり、有力視から外されることとなった。 「こいつは割と絞られたもんじゃねーの。」 銀時も答えに納得した様子を見せる。 行き先が決まり、範囲も絞られた。 「では、まずマークライト街からの調査から始めよう」 ☆ ☆ ☆ 「……ちょうどいい機会だ。マークライト街の調査と並行して、『美紗里』にも向かうとしよう。」 エンタープライズは美紗里に赤い丸を入れる。 「行かなかったの?今まで」 「……ああ、行かなかったぜ。「俺ら」はな。」 開始前中に、ジョセフ達が美紗里に行くことはなかった。 ジョセフ達もその時は他にする事もあったため、本格的な開始まで後回しにしていたからである。 そのため、『ミザリィ』はここに来てから一度も会うこともなく、 どういう相手で、どういう考えでいるのか、またどういうポジションなのか、具体的な見解には至っていなかった。 「えっ?「俺ら」って……。」 「……随分前に一度、同盟を申し込まれた相手がいた。彼らは『ミザリィ』を殺すためとな。 私達は断ったので、その件には関わってないのだが。結果は、返り討ちにされたようだ……。」 「馬鹿な奴らだぜ、まったく……。」 まだ、来てからそれほど経たない時期の事。 同盟の一人として、ジョセフにも話を持ちかけられていたことがあった。 確かに『ミザリィ』を肯定的には見てはいないが、仮にも相手は女性。 当初のジョセフ達は、彼らの考えや方向性に反対し、破談。 その翌日。知り合いから耳にした黒い噂では、"死体に上がった"というものだという。 相手にも殺意があった以上、「正当防衛」でもあり、ジョセフ達もそれだけで非難する気はなれない。 だが、問題は、敵を殺害したまま野放しにする、その"冷酷さ"が『ミザリィ』に潜んでいることであった。 それを見て、あまり見過ごしてはいられず、"要注意"とだけは認識していた。 「それに、君達も自分の目で確かめないことにはわからないだろう。……それとも、君達の方は既に会っているのか?」 「ううん。そもそも、マークライト街にも行ったことないし。」 「めんどくせーしよ。つーかわかんねーけど、案内人だろ?あんま敵っていえなくね?」 「敵ではないだろうが、中立かもしれない。場合によっては敵対する展開も否めないものだ。」 ユウキ達も美紗里には行ってはいない。 客観的に見ると、さほど対立するような関係でもないからである。 銀時は納得がいかない様子に対し、エンタープライズは"場合によっては敵対もあり得る"という見方を示した。 「ともかく。現状優先する事でないが、『ミザリィ』との接触も予定として入れるぞ。」 マークライト街の調査に続き、美紗里への訪店も予定に加えた。 「……それと、『ミザリィ』が有するサーヴァントの話だが、連中の情報から察すると、片方は『狼王ロボ』のようだ。」 「狼王ロボ?何そのアトムにでも出てそうな奴?」 「いや、ロボットじゃないぞ。セイバー。ロボという名前の狼だ。」 サーヴァントとして『狼王ロボ』を持っていることを、エンタープライズも付け加えた。 聴いた銀時はそれを"狼王と名乗るロボット"として見て、ツッコミが入れられる。 「えーと、確か、あれだよね?「シートン動物記」の一巻で書かれていた狼の事だったけ?」 「ああ、その「狼王ロボ」のことさ。君は知っているのだな。」 「へっへー!これでもボクは読書家だからねっ!」 自信満々にそう答えるユウキ。 『狼王ロボ』 「シートン動物記」にて語り継がれる狼。『ミザリィ』が所持しているとされるサーヴァントの一体であった。実際のクラスおよび姿までは未確認。 「で、もう片方は手伝いをしてた子、アビーがサーヴァントだよね。」 ユウキも出会った当初から紹介された真名を思い出す。 「アビー。『アビゲイル・ウィリアムズ』。 アメリカじゃあ、別に珍しくもなんともねえ名前なもんで、俺もそのまま聞き流していたワケだけどよォ。 やっぱし、あの『アビゲイル・ウィリアムズ』になるのよねェ~~?「セイレム」っつうところのさ。」 「17世紀末。マサチューセッツ州セイレム村で起きた「魔女裁判事件」。 事件で最初の告発者として記されている少女が、『アビゲイル・ウィリアムズ』だ。」 フォローとしてエンタープライズが簡易的な解説を入れる。 『アビゲイル・ウィリアムズ』 「魔女裁判事件」で知られる少女。『ミザリィ』が所持しているとされるサーヴァントの一体であった。実際のクラスは不明。 アメリカ出身であるジョセフもその名前にピンときていた。 「ったくサーヴァントが二体いるなんて贅沢な話だねェ~。これも主催特権ってヤツかい。」 「どうだろうか……。意味があるとも見えなくもないが。」 嫌味に捉える銀時に対し、エンタープライズはどこか二体に必要とする意味があるように捉えていた。 「悪趣味っつーか、ヘンな組み合わせっつーかさ。「ただ身を守るためにいる」って感じのサーヴァントじゃあねえよな。」 「言われてみれば、変わったチョイスだね。」 ジョセフとユウキがふと抱いた疑問。 そのチョイスには、何かの「裏」があるということ。 『狼王ロボ』と『アビゲイル・ウィリアムズ』。それは「何のためにいる」サーヴァントなのか、ちょっとした疑問があった。 ☆ ☆ ☆ 「さて、これまでで収集した情報も整理するとしよう。」 エンタープライズはホワイトボードから地図を一旦外すと、プリントアウトされた3種のドローンの画像を貼り付けた。 「まずは、ドローンの存在だ。」 横から「小型の羽ばたき型ドローン」、「武器が備わった大型の羽ばたき型ドローン」、「四輪走行する箱型の兵器」であった。 「これってこの世界のものじゃないの?」 「いや、これらはこの世界で一般的に普及されたものではない。我々が来た同時期に普及されたものだ。 微量ながら魔力も確認できた。」 目にすることの多かっただけあり、ユウキも「この世界のもの」として見ていたが、違う。 実際は何らかのサーヴァントの手が掛かったものであり、道具作成もしくは宝具などによって製造された類であった。 「そして、ドローンはこの期間中で急速に増加していた。今は都市内の殆どの地区にまで及んでいることだろう。 目に付く限りは破壊してきたが、私達の動向や存在はドローンを通して相手に監視されている可能性は高い。」 「全然、知らなかった……。」 ドローンは増加しているということはエンタープライズも確認していることであった。 その規模は、把握した限り、都市の殆どの地区にまで広まっていると見ている。 また、ドローンである以上、カメラとモニターを通じ、監視するというのも不可能ではない。 エンタープライズも、ドローンから監視されている状況に用心を抱いていた。 まじまじとドローンの写真を見ているとユウキも、どこかドローンへの心当たりを感じた。 「うん?これどっか見たことあるような……?あっ、そうだ!『二階堂ルイ』!」 ユウキはそうして自分の端末をセットし、映像が照らし出した。 空中タッチパネルの画面には、『二階堂ルイ』なるアイドルの特集ページが記載。 ルイの写真には、彼女を警護するかのように飛び回るタイプのドローンが映っていた。 「『二階堂ルイ』か。都市の中でも、獣人のアイドルとして脚光を浴びている者のようだな。 確かに、ドローンは彼女を守るように配備されている。彼女のサーヴァントの可能性は高い。」 「そいつも俺達とちょうど同じ時期に来たんだとよ。」 エンタープライズもニュースから、ルイの存在は知っていた。 銀時がアイドル事情に詳しいNPCから聴いた話では、ほぼマスターに違いないという。 「動画なんかまであるみてーだな。」 ジョセフを端末を弄って「ラプラス」を開き、二階堂ルイのチャンネル動画の、目に付く適当な動画を再生する。 新規層に「『二階堂ルイ』という人物はどういったものか」を公表し、ファンを得ようとする系のトーク動画であった。 彼女のトイプードルな容姿も相俟って、一見すると、可憐というべきか、愛嬌のある面が映されていた。 「あら、またカワイコちゃんなのね。ふゥ~~ん?」 マスコットキャラとして軽く褒めるジョセフ。 ただ、言葉と裏腹に、ジョセフの目にはルイの姿がどこか"あざとい"というか、「良く魅せようとしている」が魂胆あると映った。 別におかしなことではない。世の中には「周囲に気に入られ、自分を満たそうとする女性」もいるだろうとジョセフもわかっている。 だから、内心では素直に取り入れる気はないものの、特にそれ以上も考えるのを止め、流すこととしていた。 「……ライブをするみたいだ。」 「ライブ、だってェ?」 エンタープライズの目に留まったのは、ルイの「ライブの告知動画」であった。 「ライブ」という行動自体が、ジョセフは疑いを覚えた。 「……どう考えても、わざわざ「開始後」になってやることじゃあねえよなァ~~~。 それは「どうぞ狙ってください」っていってるようなもんだぜ?」 「言われてみれば、何かおかしいような?」 ジョセフの見解に、聴いて違和感に気付き始めるユウキ。 表舞台に出るということは、狙われるリスクも高くなる危険行為であり、まず得策とは言えない。 単純に自己顕示の為ならば、いくらでも時間のあった筈の「開始前」に済ませておくべきなのが、賢明な判断である。 「逆に考えるならば、こういうことだ。 「開始後でなければならないこと」を「狙われることになろうとも構わずにやる」。「5000人の観客」を使ってな。」 逆の発想。 「開始前」ではダメであり、「開始後」でなければならないこと。 表舞台に出ても、なお自陣にとってリターンがある話が「裏」に潜んでいるということ。 そして、その手段こそ「観客5000人」に掛かっているにあった。 それが行き着く考えとは何か。 「……魂喰いか。」 エンタープライズが答えの仮定を唱えた。 "開始前のサーヴァントによるNPCへ魂食いをし、結果死に至らしめた場合は強制退場"というルールがある。 それを踏まえた上で、魂食いという仮定で結び付けると、開始後にライブを開こうとする真意が見えてきた。 「ルイちゃんはともかくとして、裏で許可をしているサーヴァントは怪しいと思うぜ。 図々しく武装付きのドローンを放っておいて、今でもコソコソと監視してる様な奴だからよ。ロクな奴なワケがねえ。」 「魂喰いともなれば、ルイ個人の判断よりもサーヴァントの意向も大きいだろうな。」 ルイのサーヴァントが怪しいと睨むジョセフ。 この事態をルイが良いように利用されているのではないか、という点もあるとエンタープライズも判断した。 「一ヶ月半弱も待ってやることが生贄ショーってか?やることがアイドルライブつーかデスメタルじゃねーのコレ。」 「応援してくれるファンのみんなを利用するって許せないよ……。」 銀時とユウキもまた肯定的に捉えていなかった。 銀時は行動に呆れを芽生え、ユウキは行動に憤りを感じつつあった。 「なんにせよ、化けの皮を剥いでみきゃわからねえ話だ。一体どーいう了見でライブなんかやるのかってよ。」 「二階堂ルイの陣営を見極める。これはライブが始動するよりも先に済ませておく必要があるな。」 ドローンの写真を外し、ホワイトボードに書くこととした。 当初の警戒すべき相手から、「やがては倒すべき敵」と認識を切り替えることとした。 「日中にまた彼女側とのアポイントメントを取り、予定を決める。」 「何?ここでもアポゥを取らねーとダメなの?ったく、最近の聖杯戦争も手続きが面倒で、フットワークの悪い時代だねェ。」 「はぁ?アポゥ~?……どうしてそこでリンゴが出てくるワケェ?」 接触に面倒な点に、銀時も愚痴を零す。 なお、語のギャップ故か、ジョセフにはそのボケがわからなかった。 ☆ ☆ ☆ 「ユウキ達も情報があるなら聴かせてほしい。」 「ボク達も、マスターの存在についてちょっとだけ聴いてきたよ。」 "名簿にはないかも"、とバインダーを指して語るユウキ。 ユウキ達も開始前までは仕事と並行し、ハンター達やハンターとも親しい防衛隊の隊員からも聞き込みを続けていた。 「っても、いることぐらいしか突き止められなかったけどな。微妙なもんばっかだぞ。」 「今はいるって情報だけでも十分さ。深堀りについては今後、考えればいい。」 内容は少ないという銀時だが、エンタープライズはそれで了承した。 「まず、ハンターだけど。『キロランケ』って人かな。 あんまりに会わなかったんだけど、聴いた話では悪い人じゃないって感じだね。」 『キロランケ』 表向きは自然区域で主に狩猟および採集活動し、収益所などでも売買していたという。 ユウキ達とは畑違い故に直接的な接触には恵まれず、どういった陣営かは未だ不明。 「次は、『千翼』って人。防衛隊の一員……だったみたいなんだけど、 いなくなったからどういう人かはみんなわかんないって。」 『千翼』 防衛隊のロールを与えられていたのだが、早々に放棄したという。 聴いた人達の限りでは行方不明扱いとなっており、どこで何をしているかは誰も知らなかった。 「えっと、それから……」 「『エドワード・エルリック』か?」 ユウキが言うよりも先にエンタープライズが言い当てた。 「えっ、知ってるの?」 「彼から、ジョースター不動産宛に連絡があった。 サーヴァントである『空条承太郎』という男がマスターをよく知る人物だそうだ。」 『エドワード・エルリック』 彼は、防衛隊の錬金術顧問をロールとして与えられていた。 活動は自由だが、放棄はしておらず、ユウキ達にもその名は伝わっていた。 「知り合い?」 「……いや、知ってるつうか、なんつうかさぁ~~~。」 「真名を調べた限りでは、マスターの"孫"に当たるらしい。」 「孫。」 『空条承太郎』 後時代のジョセフ達と共に、宿敵『DIO』を倒したとして語られる英雄。バーサーカーのサーヴァント。 それを初めて知ったジョセフは、"二重(ダブル)ショック!!幽霊なんかに出会うよりももっと奇妙な遭遇……"。だったそうな。 「彼らとは「開始後に一度打ち合う」と約束をしている。具体的な時間も、リモートになるかも、まだ決まっていないが。」 互いのロールなどもあるため、エドワード・エルリックとは別行動にあった。 ただ、正確な時間約束はしていないため、何時にするか、どこで会うかは決まってはいなかった。 「ボク達が知るマスターとしてはこれぐらいかな? 後は……まあ、『キャッスル』と『辺獄』ぐらいとかもどうだろうかなー。」 辺境の場所について挙げるユウキ。 「『キャッスル』の方は、まあ、中世期の大っきなお城だね。」 「まんまじゃねーか。」 キャッスルの雑な紹介に、ジョセフもツッコミを入れた。 「『キャッスル』には誰かいたか?」 「そこまでわかんないや。チラッとしか見てないからね。」 「何かあるのかしれねーけど、別にそん時はサーヴァントの気配とかあったワケじゃねーし。ようわからんダンジョンだわ。」 「……まぁ、保留にしていいのかもしれないな。」 『キャッスル』 ネットでも情報が挙がらない、中世期建築による古城であった。 ユウキ達が視察した段階では、目ぼしい様には感じられず、当面は保留と判断した。 「『辺獄』の方はどーよ?月海原がスッポリ入るぐれーバカでっけえ穴みてーだけどよぉ?」 「……うーん?そこが深くてわかんないというか。一回飛んで中に入ってみたけど、何か嫌な感じがしたから引き返してきたよ……。」 「は、入ったのか君は……。」 "しょんぼり"とした様子のユウキ。 無鉄砲とも言えるユウキの行動に、少々呆れを感じるエンタープライズ。 「正直、気味の悪りぃ場所よ。あんま行きたくねーわ。」 「ここも保留だが、何かの裏はありそうだな……。」 銀時としては『辺獄』に奇妙な不快感を覚え、乗り気ではない様子であった。 エンタープライズも今は保留と流しつつ、強い疑念は拭えなかった。 『辺獄』 巨大方舟が落下したとされる謎の跡地。 深淵の穴と化した空間であり、裏に潜むものを感じるものの、当面は保留と判断した。 ☆ ☆ ☆ 「『マークライト街の調査』、『美紗里への訪店』、『二階堂ルイ陣営との接触』。 以上、三点が日中にやる予定だ。」 「異議ねえぜーー。」 「それがする事だね。わかった。」 「まぁ、それでいいんじゃねーの。」 "承知した"とばかりに、三者三様の相槌が取られる。 「それじゃあ、今日の会議はここで解散としようか。」 エンタープライズもそれ以上はないとして、解散を切り出した。 「ふわぁ~~。なーんか眠たくなっちゃった。」 「英気を養うためにも早めの睡眠に入った方がいい。今夜は起床する可能性も高いからな。」 「は~い。」 身体を伸ばしながら、部屋を出るユウキ。 (……ビッグアイはどうなってんだろ?) ふと、思い立ったように端末からニュースを開き、ビッグアイの状況を見る。 どうやら、消火活動は進んでいるようで、幸いにも被害者が出ていないことが把握できた。 情報に安堵するとユウキは空中ディスプレイを開き、端末はアイテム欄に格納した。 「マスターも早く寝るんだ。」 「はあ~~い」 ジョセフを指を指し、エンタープライズはやや厳しめな声色で告げた。 山札をシャッフルをしながら空返事で応えるジョセフに、エンタープライズも特に振り返ることなかった。 監視の再開からか、エンタープライズは部屋を後にするように霊体化していった。 「……なーーーんて言われて素直に止めちゃう俺達じゃあないのよねーーーッ。今からでも続きを……」 そうしてジョセフがUNOの山札から一枚取り出して、カードをテーブルに置く。 カードは「R(リバース)」であった。 その時、山札から一枚のカードが飛び上がった。 「でェ……。」 カードはひらひらと舞い、ジョセフの顔面に落ちる。 ジョセフが手に取ってカードを見ると、それは「S(スキップ)」であった。 そのカードに銀時も、"にやにや"とした表情を浮かべた。 「あの姉ちゃんも中々遊び気のあることすんじゃねーの。」 「……やっぱ寝るかァ。」 ジョセフは山札をテーブルの中央に置き、席を立った。 to be continued…… ============ 現存する陣営数:31組 同盟を組んだ陣営数:1組 敵対している陣営数:0組 同盟名:なし リーダー:ジョセフ・ジョースター サブリーダー:アーチャー(エンタープライズ) チームメイト:ユウキ セイバー(坂田銀時) ============ 【C-4・高層マンション(ジョセフの拠点)/聖歴111年1月1日 未明】 【ジョセフ・ジョースター@ジョジョの奇妙な冒険 Part2 戦闘潮流】 [状態]健康 [令呪]残り3画 [装備]なし [道具]エーテルマシンガン、糸、アメリカンクラッカー、波紋用の油 [所持金]10万QP [思考・状況] 基本行動方針:黒幕の打倒 1.「聖杯を決める」ための同盟を組み、戦争の早期収束へ向かう。 2.『マークライト街の調査』、『美紗里への訪店』、『二階堂ルイ陣営との接触』。 「三つとも」やらなくっちゃあならないってのがつらいところだぜ。 3.『エドとの打ち合わせ』はいつにすっかな。 [備考] 『エドワード・エルリック』と面識があり、打ち合わせが入っております。 【アーチャー(エンタープライズ)@アズールレーン】 [状態]健康 [装備]艤装弓 [道具]ジョースター不動産の顧客名簿 [所持金]潜水艦を購入できるレベルの財力(管理) [思考・状況] 基本行動方針:黒幕の打倒 1.「聖杯を決める」ための同盟を組み、戦争の早期収束へ向かう。 2.ドローンからの監視には警戒。 3.マスターとセイバー(坂田銀時)には呆れる……。 [備考] 【ユウキ@ソードアート・オンライン】 [状態]健康 [令呪]残り3画 [装備]マクアフィエル [道具]ハンターとしてのアイテム一式 [所持金]900万QP [思考・状況] 基本行動方針:最後の局面を見届ける。 1.ジョジョ達に付き合い、戦争の早期収束へ向かう。 2.『マークライト街の調査』で、『美紗里への訪店』で、『二階堂ルイ陣営との接触』だね。 3.頑張っていこう! [備考] 【セイバー(坂田銀時)@銀魂】 [状態]健康 [装備]洞爺湖 [道具]原付 [所持金]なし [思考・状況] 基本行動方針:ユウキ達を守る 1.ジョジョ達に付き合い、戦争の早期収束へ向かう。 2.まっ、気楽に行こうか。 [備考] 『亡虚の龍脈刀』は一段階の霊基再臨されない限り、使用できません。
https://w.atwiki.jp/wiki3_sai/pages/208.html
手ブレ補正を使う ツールシフトを使う 前回の基本操作に慣れてきたら、今回は割とユニークな基本機能であるSAIの手ブレ補正やツールシフトについて説明しておきます。 このページはチュートリアルというよりはただの機能解説になってますが、SAIを起動してラクガキしながら実際に各機能を試してみてください。 手ブレ補正を使う もうお気づきかもしれませんが、キャンバス上部のクイックバーに手ブレ補正という機能があります。 これは文字通り手ブレを抑えるための機能です。 ここでは補正の強さを補正なしを含めて23段階設定できるようになっています。 以下の画像では薄桃色のSAIという文字に沿って、糸を巻くようにグルグルと手を動かして引いた線を、補正0と補正S-7で比べてみました。 補正をS-7にすると、かなり補正されるのが分かると思います。 実際に手元のSAIで確かめてみるとよく分かると思いますが、ペンを激しく動かしてもカーソルがゆっくりついててくるために、実際の筆跡通りに描画されないということが分かると思います。 使いどころとしては、画面全体を横切るようなとても長い線を引く場合にはS補正で強めに補正したり、それよりも短めの時とか緊張してる時、またパソコンでの直描きやペンタブに慣れていない時など、どうしても思い通りの線が引けない場合に、適当に補正すると綺麗に引けるようになるのではと思います。 ただし、クイックバーで設定すると全てのブラシに適用されてしまうので、消しゴムでは別に補正しなくてもいいよ!とか、特定のブラシだけで使いたいけど切り替えるのが面倒だよ!という状況になることがあります。 そのような場合は以下の操作を行って、特定のブラシのみに設定しておくと良いでしょう。 任意のブラシをダブルクリック カスタムツールの設定ウィンドウで手ぶれ補正を設定するちなみにこの設定はクイックバーの設定よりも優先して機能します。※ちまちま設定するのが面倒臭い人は、消しゴムなど補正の必要の無いブラシだけ、上記の方法で手ぶれ補正を0にすると良いかも。 ツールシフトを使う ツールシフトというのはツールの切り替えを素早く行えるようになる機能です。 SAIをインストールしたばかりで特に設定を弄ってないのであれば、実際に下記を試してみて下さい。 まず鉛筆を選択します キャンバスに適当にラクガキします Eキーを押したままにすると、消しゴムに切り替わっていることに気づきます Eキーを押したまま、キャンバスを適当に消します Eキーを離し、ペンを浮かします(マウス左ボタンから指を離す) ブラシが自動的に鉛筆に戻ります つまり、切り替えた後のブラシのキーを離す&描画を止めると、切り替える前のブラシに戻る、というのがツールシフトです。 各ツールに割り当てられたキーを変更する場合は、ブラシをダブルクリック カスタムツールの設定のショートカットの欄に好きな英字を入力とします。 また下の画像の固定ツールとカスタムツールトレイ内の全てのツールでツールシフトを利用することが可能です。 ちなみにデフォルトでは250ミリ秒以内のキー押下であれば、ツールシフトが機能しないようになっています。 250ミリ秒というのはキーを適当にポチッと押してすぐ離すくらいです。 この場合は例えば、Eキーをポチッと押してすぐ離すと消しゴムになったまま鉛筆には戻りません。 これを自分のスタイルに合わせて設定変更したい場合は、SAIメニューバーのその他 オプション ツールタブで表示される以下のウィンドウで変更することができます。 使用例1. ブラシを2~3個しか使わないという人は、ツールシフトと判定するまでのキー押下時間を0ミリ秒にすることでメインのブラシを軸に常にツールシフトを使うことができる。 この場合ツール選択キー押下中にストロークを開始したらツールシフトとみなすのON/OFFは関係が無い。2. ブラシやツールをいくつも切り替えながら使う人は、ツールシフトと判定するまでのキー押下時間を長めに設定して、メインブラシを切り替える時は短めキーを押して切り替えて、サブブラシを使う時は長く押してツールシフトする。 またツール選択キー押下中にストロークを開始したらツールシフトとみなすにチェックを入れておけばキー押下時間を気にせず、描画を始めたらすぐキーを離してもツールシフトが機能する。3. ツールシフトが肌に合わない人はツールシフトを使用するのチェックを外してツールシフト機能をOFFにすれば、普通にツールが切り替わるだけになる。 SAIの方向性SAIの良いところというのは結局のところ描きやすさに尽きます。 発売以前からよく言われていたことではありますが、確かに機能的にはお世辞にも豊富だとは言えず、PCのソフトという大枠で考えた時に、何ができるかを知っている人にとっては物足りなさを感じるはずです。 ようするにSAIは「あれができたら良いのに」ではなく「あれはこうだったら良いのに」みたいな概念、方向性をもって開発されたのだと個人的には思います。それは恐らく、既にPhotoshopやPainterなど大御所のこれまでのバージョンアップによって「何ができるか」という方向性は底が見えはじめていたからでしょう。 それだけ豊かになったということでもあります。 だから、SAIのような方向性の違うソフトが最近増えているのは、技術的にもある意味必然的な流れなのだろうと思います。 5.ペン入れツールを使うへすすむ 3.基本操作編へもどる このページ内で分かりづらい部分があれば指摘してください。 名前 コメント
https://w.atwiki.jp/1014r/pages/25.html
ガチャで排出される最高レアリティは★3! ゲットしたあとに育成素材を使って★4、★5に覚醒することが出来ます。 ★4、★5に覚醒する時に必要な★3カードは1枚でOK! 千銃士Rはカードの覚醒には覚醒用のアイテム(カードの記憶とUC)で覚醒するので、同じカードの複数枚狙いは不要です。 チュートリアルガチャに実装していない貴銃士 NPCキャラや、まだ限定カードしかない貴銃士がいるので、これから始める方は気になる貴銃士がいるか確認してみましょう チュートリアルガチャに実装していない貴銃士 ゴースト 現時点でNPC キセル 現時点でNPC ベネッタ 現時点でNPC カルカノーレ 現時点でNPC スケレット cv福山潤現時点でNPC チュートリアルガチャで排出される★3カード一覧 誰かのオススメや強さで選ぶより、自分気になる貴銃士を引くのがオススメ! 画像 キャラ名 属性 カード名 マークス(CV.熊谷健太郎) 勇敢 首輪をつけて マークス(CV.熊谷健太郎) 混沌 始まりは、月夜 ライク・ツー(CV.広瀬裕也) 混沌 路地裏の追跡 ライク・ツー(CV.広瀬裕也) 知性 どんな代償を払おうとも エンフィールド(CV.鈴木勝吾) 規律 愛故に、と暗がりに謳う エンフィールド(CV.鈴木勝吾) 知性 誰も知らない微小の意味 スナイダー(CV.柿原徹也) 混沌 伏して睨む スナイダー(CV.柿原徹也) 知性 ウィンズダム城の亡霊 ジョージ(CV.八代拓) 規律 薔薇の記憶 ジョージ(CV.八代拓) 勇敢 雨上がりの太陽 ケンタッキー(CV.梶裕貴) 規律 星条旗に放つ想い ケンタッキー(CV.梶裕貴) 勇敢 自由の砂浜 ペンシルヴァニア(CV.伊東健人) 知性 覚悟の視線 ペンシルヴァニア(CV.伊東健人) 技巧 夜の森、人の領域 スプリングフィールド(CV.蒼井翔太) 技巧 林檎色の夕焼け スプリングフィールド(CV.蒼井翔太) 規律 星に願うこと シャルルヴィル(CV.立花慎之介) 技巧 白百合の秘密の庭 シャルルヴィル(CV.立花慎之介) 規律 さよなら、世界 シャスポー(CV.江口拓也) 規律 小夜啼鳥の籠 シャスポー(CV.江口拓也) 勇敢 赤の足音 グラース(CV.寺島拓篤) 混沌 パリジャンの午後 グラース(CV.寺島拓篤) 勇敢 許され得ぬは誰の行い タバティエール(CV.高橋広樹) 知性 失意の雨 ドライゼ(CV.佐藤拓也) 勇敢 鉄の掟、鉄の意思 ドライゼ(CV.佐藤拓也) 技巧 真紅の番人 エルメ(CV.諏訪部順一) 知性 完璧主義の鉄の秘密 エルメ(CV.諏訪部順一) 技巧 その邂逅は鉄錆の香 ジーグブルート(CV.笠間淳) 知性 独り、非道を往く末 十手(CV.田所陽向) 混沌 花に酔う 十手(CV.田所陽向) 技巧 鈴の音と嘘の代償 邑田(CV.深町寿成) 混沌 狐火 在坂(CV.植田圭輔) 技巧 水底より光仰ぐ 八九(CV.鈴村健一) 混沌 突撃!隣のゲーム部屋 カール(CV.山谷祥生) 混沌 赤き死神 カール(CV.山谷祥生) 勇敢 墓標に眠る ローレンツ(CV.西山宏太朗) 勇敢 崇高なる非道に花束を ローレンツ(CV.西山宏太朗) 知性 リーディングルーティーン ベルガー(CV.豊永利行) 技巧 宮殿の破壊者 ベルガー(CV.豊永利行) 混沌 檻の中の友達 ファル(CV.前野智昭) 知性 喪失の音色 ファル(CV.前野智昭) 技巧 絶望の先で嗤う カトラリー(CV.松岡禎丞) 勇敢 孤独な晩餐 カトラリー(CV.松岡禎丞) 技巧 幸せの味 ミカエル(CV.野島健児) 規律 天使のレクイエム